package ewms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ewms.bo.EwmsWasteDeclareAddBo;
import ewms.bo.EwmsWasteDeclareEditBo;
import ewms.bo.EwmsWasteDeclareQueryBo;
import ewms.domain.EwmsWasteDeclare;
import ewms.mapper.EwmsWasteDeclareMapper;
import ewms.service.IEwmsWasteDeclareService;
import ewms.utils.EwmsUtils;
import ewms.vo.EwmsWasteDeclareVo;
import ewms.common.core.domain.FileEntity;
import ewms.common.core.page.PagePlus;
import ewms.common.core.page.TableDataInfo;
import ewms.common.exception.CustomException;
import ewms.common.utils.PageUtils;
import ewms.domain.EwmsWasteDetail;
import ewms.mapper.EwmsWasteDetailMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 危废申报Service业务层处理
 *
 * @author zhaoxiaochun
 * @date 2022-01-12
 */
@Service
public class EwmsWasteDeclareServiceImpl extends ServiceImpl<EwmsWasteDeclareMapper, EwmsWasteDeclare> implements IEwmsWasteDeclareService {

	@Autowired
	private EwmsWasteDetailMapper ewmsWasteDetailMapper;

	@Override
	public EwmsWasteDeclareVo queryById(Long wasteDeclareId) {
		EwmsWasteDeclare ewmsWasteDeclare = baseMapper.selectById(wasteDeclareId);
		String attachment = Optional.ofNullable(ewmsWasteDeclare).orElse(null).getAttachment();
		return Optional.ofNullable(BeanUtil.toBean(ewmsWasteDeclare, EwmsWasteDeclareVo.class)).orElse(null)
			.setFileList(JSON.parseObject(attachment, new TypeReference<List<FileEntity>>() {
			}.getType()));
	}

	@Override
	public TableDataInfo<EwmsWasteDeclareVo> queryPageList(EwmsWasteDeclareQueryBo bo) {
		PagePlus<EwmsWasteDeclare, EwmsWasteDeclareVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), ewmsWasteDeclares ->
			ewmsWasteDeclares.stream().map(ewmsWasteDeclare ->
			{
				EwmsWasteDeclareVo ewmsWasteDeclareVo = BeanUtil.toBean(ewmsWasteDeclare, EwmsWasteDeclareVo.class);
				if (StrUtil.isNotBlank(ewmsWasteDeclare.getAttachment())) {
					ewmsWasteDeclareVo.setFileList(JSON.parseObject(ewmsWasteDeclare.getAttachment(), new TypeReference<List<FileEntity>>() {
					}.getType()));
				}
				return ewmsWasteDeclareVo;
			}).collect(Collectors.toList())
		);
		return PageUtils.buildDataInfo(result);
	}

	@Override
	public List<EwmsWasteDeclareVo> queryList(EwmsWasteDeclareQueryBo bo) {
		return listVo(buildQueryWrapper(bo), EwmsWasteDeclareVo.class);
	}

	@Override
	public TableDataInfo<EwmsWasteDeclareVo> selectPageList(EwmsWasteDeclareQueryBo bo) {
		return PageUtils.buildDataInfo(baseMapper.selectPageWasteDeclareList(PageUtils.buildPage(), bo));
	}

	@Override
	public List<EwmsWasteDeclareVo> selectList(EwmsWasteDeclareQueryBo bo) {
		return baseMapper.selectWasteDeclareList(bo);
	}

	private LambdaQueryWrapper<EwmsWasteDeclare> buildQueryWrapper(EwmsWasteDeclareQueryBo bo) {
		Map<String, Object> params = bo.getParams();
		LambdaQueryWrapper<EwmsWasteDeclare> lqw = Wrappers.lambdaQuery();
		lqw.like(StrUtil.isNotBlank(bo.getWasteName()), EwmsWasteDeclare::getWasteName, bo.getWasteName());
		lqw.like(StrUtil.isNotBlank(bo.getBatchNumber()), EwmsWasteDeclare::getBatchNumber, bo.getBatchNumber());
		lqw.between(params.get("beginDeclareDate") != null && params.get("endDeclareDate") != null,
			EwmsWasteDeclare::getDeclareDate, params.get("beginDeclareDate"), params.get("endDeclareDate"));
		return lqw;
	}

	/**
	 * 危废申报
	 *
	 * @param bo 危废申报新增业务对象
	 * @return
	 */
	@Override
	public Boolean insertByAddBo(EwmsWasteDeclareAddBo bo) {
		EwmsWasteDeclare add = BeanUtil.toBean(bo, EwmsWasteDeclare.class);
		add.setDeclareDate(EwmsUtils.handleSelectDate(add.getDeclareDate()));
		EwmsWasteDetail ewmsWasteDetail = ewmsWasteDetailMapper.selectById(bo.getWasteId());
		if (Objects.isNull(ewmsWasteDetail)) {
			throw new CustomException("危废信息未找到！");
		}
		add.setWasteName(ewmsWasteDetail.getWasteName());

		// generate batch code EWMS20220105001-001
		// 1. 第一部分: EWMS
		StringJoiner batchStringJoin = new StringJoiner("");
		batchStringJoin.add("EWMS");

		// 2. 第二部分：年月日 格式化为 yyyyMMdd 格式
		String twoPart = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
		batchStringJoin.add(twoPart);

		// 3.第三部分： 三位大批次号
		LambdaQueryWrapper<EwmsWasteDeclare> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.between(EwmsWasteDeclare::getDeclareDate, DateUtil.beginOfDay(new Date()), DateUtil.endOfDay(new Date()))
			.orderByDesc(EwmsWasteDeclare::getWasteDeclareId).last("LIMIT 1");
		EwmsWasteDeclare wasteDeclare = this.getOne(queryWrapper);
		String threePart = "";
		if (Objects.nonNull(wasteDeclare)) {
			String batchNumber = wasteDeclare.getBatchNumber();
			int number = Integer.valueOf(batchNumber.substring(batchNumber.length() - 7, batchNumber.length() - 4)) + 1;
			threePart = String.format("%03d", number);
		} else {
			threePart = "001";
		}
		batchStringJoin.add(threePart);

		// 4.第四部分: 三位小批次号
		boolean saveFlag = true;
		boolean canSplit = bo.getIsCanSplit();
		if (canSplit && bo.getSplitCount() > 1) {
			String tempBatchStr = batchStringJoin.toString();
			// 拆分预估重量
			BigDecimal wasteDiscreetWeight = bo.getWasteDiscreetWeight();
			BigDecimal divideWeight = wasteDiscreetWeight.divide(BigDecimal.valueOf(bo.getSplitCount()), 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP);
			for (int i = 0; i < bo.getSplitCount(); i++) {
				EwmsWasteDeclare copyAdd = new EwmsWasteDeclare();
				BeanUtil.copyProperties(add, copyAdd);
				if (i == 0 && bo.getFileList() != null && bo.getFileList().size() > 0) {
					copyAdd.setAttachment(JSON.toJSONString(bo.getFileList()));
				}
				StringJoiner sj = new StringJoiner("-");
				sj.add(tempBatchStr);
				sj.add(String.format("%03d", (i + 1)));
				copyAdd.setBatchNumber(sj.toString());
				copyAdd.setWasteDiscreetWeight(divideWeight);
				validEntityBeforeSave(add);
				saveFlag &= this.save(copyAdd);
			}
		} else {
			batchStringJoin.add("-001");
			add.setBatchNumber(batchStringJoin.toString());
			if (bo.getFileList() != null && bo.getFileList().size() > 0) {
				add.setAttachment(JSON.toJSONString(bo.getFileList()));
			}
			validEntityBeforeSave(add);
			saveFlag &= this.save(add);
		}
		return saveFlag;
	}

	@Override
	public Boolean updateByEditBo(EwmsWasteDeclareEditBo bo) {
		EwmsWasteDeclare update = BeanUtil.toBean(bo, EwmsWasteDeclare.class);
		if (bo.getFileList() != null && bo.getFileList().size() > 0) {
			update.setAttachment(JSON.toJSONString(bo.getFileList()));
		} else {
			update.setAttachment("");
		}
		validEntityBeforeSave(update);
		return updateById(update);
	}

	/**
	 * 保存前的数据校验
	 *
	 * @param entity 实体类数据
	 */
	private void validEntityBeforeSave(EwmsWasteDeclare entity) {
		//TODO 做一些数据校验,如唯一约束
	}

	@Override
	public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
		if (isValid) {
			//TODO 做一些业务上的校验,判断是否需要校验
		}
		return removeByIds(ids);
	}
}
